#if 1
#include <iostream>
#include <memory>
using namespace std;
class Test
{
public:
    Test(string s)
    {
        str = s;
        cout << "Test create." << endl;
    }
    ~Test()
    {
        cout << "Test delete:" << str << endl;
    }
    string &get_str()
    {
        return str;
    }
    void set_str(string s)
    {
        str = s;
    }
    void print()
    {
        cout << str << endl;
    }

private:
    string str;
};

unique_ptr<Test> fun()
{
    return unique_ptr<Test>(new Test("789"));
}

unique_ptr<Test> fun2()
{
    return unique_ptr<Test>(new Test("789"));
}
int main()
{
    {
        unique_ptr<Test> ptest(new Test("123"));
        unique_ptr<Test> ptest2(new Test("456"));
        ptest->print(); //123

        ptest.swap(ptest2);
        cout << "交换过后的数据" << endl;
        ptest->print();
        ptest2->print();

        //不能直接赋值ptest2=ptest,
        //调用move后ptest2原来的对象会被释放;
        //ptest2对象指向原本ptest对象的内存,
        //输出Test delete 456
        ptest2 = move(ptest);

        // ptest2 = ptest;
        //因为两个unique_ptr不能指向同一内存地址
        //所以经过前面move后ptest会被赋值NULL,
        //输出ptest=NULL
        if (ptest == NULL)
            cout << "ptest=NULL" << endl;

        //release成员函数把ptest2指针赋值为空,
        //但是并没有释放指针指向的内存;
        //所以此时p指针指向原本ptest2指向的内存;
        Test *p = ptest2.release();
        p->print(); //123

        //重新绑定对象,原来的对象会被释放掉
        //但是次ptest对象本来就被释放过了;
        //所以这里就不会再调用析构函数了
        ptest.reset(p);

        //这里可以用=
        //因为使用了移动构造函数,
        //函数返回一个unique_ptr会自动调用移动构造函数.
        ptest2 = fun(); //等价为ptest2 = std::move();
        ptest2->print();
    }
    return 0;
}

#endif